//package org.springframework.web.context.request;
//
//import org.springframework.core.NamedInheritableThreadLocal;
//import org.springframework.core.NamedThreadLocal;
//import org.springframework.lang.Nullable;
//import org.springframework.util.ClassUtils;
//
///**
// * Created by liyufeng on 2022/5/15
// */
// * 覆盖RequestContextHolder
//public abstract class RequestContextHolder {
//
//    private static final boolean jsfPresent =
//            ClassUtils.isPresent("javax.faces.context.FacesContext", RequestContextHolder.class.getClassLoader());
//
//    private static final ThreadLocal<RequestAttributes> requestAttributesHolder =
//            new NamedThreadLocal<>("Request attributes");
//
//    private static final ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder =
//            new NamedInheritableThreadLocal<>("Request context");
//
//
//    /**
//     * Reset the RequestAttributes for the current thread.
//     */
//    public static void resetRequestAttributes() {
//        requestAttributesHolder.remove();
//        inheritableRequestAttributesHolder.remove();
//    }
//
//    /**
//     * Bind the given RequestAttributes to the current thread,
//     * <i>not</i> exposing it as inheritable for child threads.
//     * @param attributes the RequestAttributes to expose
//     * @see #setRequestAttributes(RequestAttributes, boolean)
//     */
//    public static void setRequestAttributes(@Nullable RequestAttributes attributes) {
//        setRequestAttributes(attributes, false);
//    }
//
//    /**
//     * Bind the given RequestAttributes to the current thread.
//     * @param attributes the RequestAttributes to expose,
//     * or {@code null} to reset the thread-bound context
//     * @param inheritable whether to expose the RequestAttributes as inheritable
//     * for child threads (using an {@link InheritableThreadLocal})
//     */
//    public static void setRequestAttributes(@Nullable RequestAttributes attributes, boolean inheritable) {
//        if (attributes == null) {
//            resetRequestAttributes();
//        }
//        else {
//            if (inheritable) {
//                inheritableRequestAttributesHolder.set(attributes);
//                requestAttributesHolder.remove();
//            }
//            else {
//                requestAttributesHolder.set(attributes);
//                inheritableRequestAttributesHolder.remove();
//            }
//        }
//    }
//
//    /**
//     * Return the RequestAttributes currently bound to the thread.
//     * @return the RequestAttributes currently bound to the thread,
//     * or {@code null} if none bound
//     */
//    @Nullable
//    public static RequestAttributes getRequestAttributes() {
//        RequestAttributes attributes = requestAttributesHolder.get();
//        if (attributes == null) {
//            attributes = inheritableRequestAttributesHolder.get();
//        }
//        return attributes;
//    }
//
//    /**
//     * Return the RequestAttributes currently bound to the thread.
//     * <p>Exposes the previously bound RequestAttributes instance, if any.
//     * Falls back to the current JSF FacesContext, if any.
//     * @return the RequestAttributes currently bound to the thread
//     * @throws IllegalStateException if no RequestAttributes object
//     * is bound to the current thread
//     * @see #setRequestAttributes
//     * @see ServletRequestAttributes
//     * @see FacesRequestAttributes
//     * @see javax.faces.context.FacesContext#getCurrentInstance()
//     */
//    public static RequestAttributes currentRequestAttributes() throws IllegalStateException {
//        RequestAttributes attributes = getRequestAttributes();
//        if (attributes == null) {
//            if (jsfPresent) {
//                attributes = FacesRequestAttributesFactory.getFacesRequestAttributes();
//            }
//            if (attributes == null) {
//                throw new IllegalStateException("No thread-bound request found: " +
//                        "Are you referring to request attributes outside of an actual web request, " +
//                        "or processing a request outside of the originally receiving thread? " +
//                        "If you are actually operating within a web request and still receive this message, " +
//                        "your code is probably running outside of DispatcherServlet: " +
//                        "In this case, use RequestContextListener or RequestContextFilter to expose the current request.");
//            }
//        }
//        return attributes;
//    }
//
//
//    /**
//     * Inner class to avoid hard-coded JSF dependency.
//     */
//    private static class FacesRequestAttributesFactory {
//
//        @Nullable
//        public static RequestAttributes getFacesRequestAttributes() {
//            FacesContext facesContext = FacesContext.getCurrentInstance();
//            return (facesContext != null ? new FacesRequestAttributes(facesContext) : null);
//        }
//    }
//
//}
